package zouran.controller;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import zouran.entity.FireCenter;
import zouran.exception.MyRunTimeException;
import zouran.result.ErrorMessage;
import zouran.result.ResultMap;
import zouran.service.EarthquakeInfoService;
import zouran.service.FireCenterService;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;

/**
 * FireCenter Api
 * Author：zouran
 * Date：2023/3/31  21:48
 * Description:
 */
@RestController
@Validated
public class FireCenterController {
    static Integer MAX_FIRE_CENTER_COUNT = 30;
    private final EarthquakeInfoService earthquakeInfoService;
    private final FireCenterService fireCenterService;
    private final ResultMap<FireCenter> resultMap;

    public FireCenterController(EarthquakeInfoService earthquakeInfoService, FireCenterService fireCenterService, ResultMap<FireCenter> resultMap) {
        this.earthquakeInfoService = earthquakeInfoService;
        this.fireCenterService = fireCenterService;
        this.resultMap = resultMap;
    }

    /**
     * @param file    文件
     * @param project 文件夹存放名字
     * @return 路径
     */
    @PostMapping("/markdown")
    public ResultMap<String> saveArticleImagesTypora(@RequestParam("file") @NotNull MultipartFile file, @RequestParam("project") @NotNull String project) throws IOException {
        String filename = file.getOriginalFilename();
        String extName = null;
        if (filename != null) {
            extName = filename.substring(filename.lastIndexOf('.'));
        }
        String fileName = System.currentTimeMillis() + extName;
        String fileFullName = "/home/file/markdown/" + project + "/" + fileName;
        File localFile = new File(fileFullName);
        File parentFile = localFile.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        file.transferTo(localFile);
        // nginx地址
        return resultMap.success("https://file.zouran.top/markdown/" + project + "/" + fileName);
    }

    /**
     * 访问接口文档
     */
    @RequestMapping("/apidoc")
    public void apidoc(HttpServletResponse httpServletResponse) throws IOException {
        httpServletResponse.sendRedirect("https://www.apifox.cn/apidoc/shared-8ad9490a-8369-494a-a961-b8ce5ad24d40");
    }

    /**
     * 全部消防站
     */
    @RequestMapping("/getAllFireCenter")
    public ResultMap getAllFireCenter() {
        return resultMap.success(fireCenterService.getAllFireCenter());
    }


    /**
     * id获取消防站
     *
     * @param fireCenterId 消防站编号
     * @return 消防站信息
     */
    @RequestMapping("/getFireCenterByFireCenterId")
    public ResultMap getFireCenterByFireCenterId(@RequestParam("fireCenterId") long fireCenterId) {
        return resultMap.success(fireCenterService.getFireCenterByFireCenterId(fireCenterId));
    }


    /**
     * 地震id获取附近消防站
     *
     * @param earthquakeId 地震编号
     * @return 消防站列表
     */
    @RequestMapping("/getAllNearFireCenterByEarthquakeId")
    public ResultMap getAllNearFireCenterByEarthquakeId(@RequestParam("earthquakeId") Long earthquakeId) {
        if (!earthquakeInfoService.judgeEarthquakeInfoExistById(earthquakeId))
            throw new MyRunTimeException(ErrorMessage.EARTHQUAKE_ID_ERROR.getMessage());
        return resultMap.success(fireCenterService.getAllNearFireCenterByEarthquakeId(earthquakeId));
    }

    /**
     * 地震id获取附近消防站
     *
     * @param earthquakeId 地震编号
     * @return 消防站坐标列表
     */
    @RequestMapping("/getAllNearFireCenterPositionByEarthquakeId")
    public ResultMap getAllNearFireCenterPositionByEarthquakeId(@RequestParam("earthquakeId") Long earthquakeId) {
        if (!earthquakeInfoService.judgeEarthquakeInfoExistById(earthquakeId))
            throw new MyRunTimeException(ErrorMessage.EARTHQUAKE_ID_ERROR.getMessage());
        return resultMap.success(fireCenterService.getAllNearFireCenterPositionByEarthquakeId(earthquakeId));
    }


    /**
     * 选点附近消防站
     *
     * @param lon         经度
     * @param lat         纬度
     * @param lonDistance 长轴
     * @param latDistance 短轴
     * @return 消防站信息列表
     */
    @RequestMapping("/getAllNearFireCenterPositionByPosition")
    public ResultMap getAllNearFireCenterPositionByPosition(@RequestParam("longitude") @Min(0) @Max(180) Double lon, @RequestParam("latitude") @Min(0) @Max(180) Double lat, @RequestParam("lonDistance") Double lonDistance, @RequestParam("latDistance") Double latDistance) {
        return resultMap.success(fireCenterService.getAllNearFireCenterPositionByPosition(lon, lat, lonDistance, latDistance));
    }

    /**
     * 选点附近消防站坐标
     *
     * @param lon         经度
     * @param lat         纬度
     * @param lonDistance 长轴
     * @param latDistance 短轴
     * @return 消防站位置信息列表
     */
    @RequestMapping("/getAllNearFireCenterByPosition")
    public ResultMap getAllNearFireCenterByPosition(@RequestParam("longitude") @Min(0) @Max(180) Double lon, @RequestParam("latitude") @Min(0) @Max(180) Double lat, @RequestParam("lonDistance") Double lonDistance, @RequestParam("latDistance") Double latDistance) {
        return resultMap.success(fireCenterService.getAllNearFireCenterByPosition(lon, lat, lonDistance, latDistance));
    }


    /**
     * 物资分配
     *
     * @param earthquakeId    地震编号
     * @param fireCenterCount 物资分配总数量
     * @return 分配结果列表
     */
    @RequestMapping("/getNearFireCenterWeightByEarthquakeId")
    public ResultMap getNearFireCenterWeightByEarthquakeId(@RequestParam("earthquakeId") Long earthquakeId, @RequestParam("fireCenterCount") Integer fireCenterCount) {
        if (fireCenterCount >= MAX_FIRE_CENTER_COUNT) {
            throw new MyRunTimeException(400, "fireCenterCount超出可分配范围");
        }
        if (!earthquakeInfoService.judgeEarthquakeInfoExistById(earthquakeId))
            throw new MyRunTimeException(ErrorMessage.EARTHQUAKE_ID_ERROR.getMessage());
        return resultMap.success(fireCenterService.getNearFireCenterWeightByEarthquakeId(earthquakeId, fireCenterCount));
    }
}
